﻿// Gateway.Api 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证（版本 2.0）进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动！任何基于本项目二次开发而产生的一切法律纠纷和责任，我们不承担任何责任！

using Aurora.AI.Abstractions;
using Aurora.AI.Abstractions.Embeddings;
using Aurora.AI.Abstractions.ObjectModels.RequestModels;
using Aurora.AI.Abstractions.ObjectModels.ResponseModels;
using Aurora.AI.Common.Extensions;
using Aurora.AI.MetaGLM.Models.RequestModels;
using Microsoft.Extensions.Logging;

namespace Aurora.AI.MetaGLM.Embeddings;

public class MetaGLMTextEmbeddingService : IAuroraAITextEmbeddingService
{
    private readonly MetaGLMPlatformOptions _openAiOptions;
    private readonly ILogger<MetaGLMTextEmbeddingService> _logger;
    public MetaGLMTextEmbeddingService(ILogger<MetaGLMTextEmbeddingService> logger)
    {
        _logger = logger;
        _openAiOptions = new MetaGLMPlatformOptions
        {
            Client = new MetaGLMClientV4()
        };
    }

    public async Task<EmbeddingCreateResponse> EmbeddingAsync(EmbeddingCreateRequest createEmbeddingModel,
        AuroraAIPlatformOptions? options = null,
        CancellationToken cancellationToken = default)
    {
        // var embeddingRequestBase = new EmbeddingRequestBase();
        // embeddingRequestBase.SetModel(createEmbeddingModel.Model);
        // 判断大小
        // 最大的批次是 一次 25条
        int count = createEmbeddingModel.InputCalculated.Count;
        EmbeddingCreateResponse response = new()
        {
            Model = createEmbeddingModel.Model,
        };
        // 如果大于25条 则进行 分批处理
        if (count > 10)
        {
            bool next = true;
            int page = 1;
            int size = 10;
            while (next)
            {
                var data = createEmbeddingModel.InputCalculated.Skip((page - 1) * size).Take(size).ToList();
                if (data.Count > 0)
                {
                    await SendAsync(createEmbeddingModel.Model, data, response, options);
                }
                else
                {
                    next = false;
                }

                page++;
            }
        }
        else
        {
            await SendAsync(createEmbeddingModel.Model, createEmbeddingModel.InputCalculated.ToList(),
                response, options);
        }
        return response;
    }

    private Task SendAsync(string model, List<string> data, EmbeddingCreateResponse response,
        AuroraAIPlatformOptions? options = null)
    {
        var embeddingRequestBase = new EmbeddingRequestBase();
        embeddingRequestBase.SetModel(model);
        embeddingRequestBase.SetInput(data);
        var result = _openAiOptions.Client!.Embeddings.Process(embeddingRequestBase, options.ApiKey);
        if (response.Data == null)
        {
            response.Data = new List<EmbeddingResponse>();
        }
        if (result.error != null)
        {
            if (response.Error == null)
                response.Error = new();
            _logger.LogError("[MetaGLM] embedding 异常："+AuroraAIJsonSerializer.Serialize(result.error));
            response.Error.Message = AuroraAIJsonSerializer.Serialize(result.error);
        }

        if (result.data != null)
            response.Data.AddRange(result.data.Select(x => new EmbeddingResponse()
            {
                Embedding = x.embedding.ToList(),
                Index = x.index
            }).ToList());
        return Task.CompletedTask;
    }
}